﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using BakalarskaPraca.Generation.Data;
using BakalarskaPraca.Generation.Tasks.Abstract;
using BakalarskaPraca.Interfaces;

namespace BakalarskaPraca.Forms.Controls
{
    public partial class GenerationRunner : UserControl, IProgressReporter
    {
        private readonly List<GenerationProcess> _generationProcesses;
        private readonly int _stages;
        private int _currentStage;
        private GenerationProcess _currentProcess;
        private readonly string _name;
        public bool Completed;
        private Action _completionCallback; 

        public GenerationRunner(MarkedPolygonGroup group, Action completionCallback)
        {
            InitializeComponent();
            this._generationProcesses = new List<GenerationProcess>(group.GenerationInstructions);
            this._stages = this._generationProcesses.Count();
            this._name = group.Name;
            this._completionCallback = completionCallback;
        }

        public void RunGeneration()
        {
            this.GenerationThread.RunWorkerAsync();
        }

        private void GenerationThreadDoWork(object sender, DoWorkEventArgs e)
        {
            while(!this.IsHandleCreated)
            {
                Thread.Sleep(10);
            }
            
            while(this._generationProcesses.Any())
            {
                this.GenerationThread.ReportProgress(this._currentStage);
                this._currentProcess = this._generationProcesses.First();
                this._generationProcesses.Remove(this._currentProcess);
                //this.MessageLabel.Text = (this._name + " - " + this._currentProcess.ToString()); 
                this.ReportProgressMessage(this._currentProcess.ToString());
                this._currentProcess.Run(this);
            }
        }

        private void GenerationThreadProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this._currentStage++; 
            this.StageLabel.Text = ((this._currentStage + "/" + this._stages));
        }

        private void GenerationThreadRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.MessageLabel.Text = (this._name + " - COMPLETED");
            this.Completed = true;
            this.MainProgressBar.Value = this.MainProgressBar.Maximum;
            this._completionCallback();
        }

        public void ReportProgress(int currentState, int targetState)
        {
            this.Invoke((MethodInvoker) delegate
                                            {
                                                this.MainProgressBar.Maximum = targetState;
                                                this.MainProgressBar.Value = currentState;
                                            });
        }

        public void ReportProgressMessage(string message)
        {
            this.Invoke((MethodInvoker) delegate
                                            {
                                                this.MessageLabel.Text = this._name + " - " + message;
                                            });
        }
    }
}
